package com.oschat.controller;

import com.oschat.annotation.GlobalInterceptor;
import com.oschat.entity.constants.Constants;
import com.oschat.entity.dto.TokenUserInfoDto;
import com.oschat.entity.po.UserInfo;
import com.oschat.entity.vo.ResponseVO;
import com.oschat.entity.vo.UserInfoVO;
import com.oschat.exception.BusinessException;
import com.oschat.redis.RedisComponent;
import com.oschat.redis.RedisUtils;
import com.oschat.service.UserInfoService;
import com.oschat.utils.CopyTools;
import com.wf.captcha.SpecCaptcha;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @Description 用户控制层
 * @Classname AccountController
 * @Date 2024/10/30 19:33
 * @Created by panda
 */
@Slf4j
@RestController("accountController")
@RequestMapping("/account")
@Validated
public class AccountController extends ABaseController {

    @Resource
    private RedisUtils redisUtils;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private RedisComponent redisComponent;


    /**
     * @description: 校验图形验证码
     * @param:
     * @return: com.oschat.entity.vo.ResponseVO
     * @author Administrator
     * @date: 2025/2/10 17:03
     */
    @RequestMapping("/checkCode")
    public ResponseVO captcha() {
        SpecCaptcha specCaptcha = new SpecCaptcha(100, 42, 4);//验证码图形
        String code = specCaptcha.text().toLowerCase();//验证码结果
        String checkCodeKey = UUID.randomUUID().toString();
        log.info("验证码是:{}", code);
        // 存入redis并设置过期时间为1分钟
        redisUtils.setex(Constants.REDIS_KEY_CHECK_CODE + checkCodeKey, code, Constants.REDIS_TIME_1MIN);
        // 将key和base64返回给前端
        String checkCodeKey64 = specCaptcha.toBase64();
        Map<String, String> result = new HashMap<>();

        result.put("checkCode", checkCodeKey64);
        result.put("checkCodeKey", checkCodeKey);
        return getSuccessResponseVO(result);
    }

    /**
     * @description: 用户注册
     * @param: checkCodeKey
     * email
     * password
     * nickName
     * checkCode
     * @return: com.oschat.entity.vo.ResponseVO
     * @author Administrator
     * @date: 2025/2/10 17:31
     */
    @RequestMapping("/register")
    public ResponseVO register(@NotEmpty String checkCodeKey,
                               @NotEmpty @Email String email,
                               @NotEmpty @Pattern(regexp = Constants.REGEX_PASSWORD) String password,
                               @NotEmpty String nickName,
                               @NotEmpty String checkCode) {
        try {
            if (!checkCode.equalsIgnoreCase((String) redisUtils.get(Constants.REDIS_KEY_CHECK_CODE + checkCodeKey))) {
                throw new BusinessException("图片验证码不正确");
            }
            userInfoService.register(email, nickName, password);
        } finally {
            redisUtils.delete(Constants.REDIS_KEY_CHECK_CODE + checkCodeKey);
        }
        return getSuccessResponseVO(null);
    }

    /**
     * description: 用户登录
     *
     * @since: 1.0.0
     * @author: 作者拼音或者英文名称
     * @date: 2024/11/1 14:26
     */
    @RequestMapping("/login")
    public ResponseVO login(@NotEmpty String checkCodeKey,
                            @NotEmpty @Email String email,
                            @NotEmpty String password,
                            @NotEmpty String checkCode) {
        try {
            if (!checkCode.equalsIgnoreCase((String) redisUtils.get(Constants.REDIS_KEY_CHECK_CODE + checkCodeKey))) {
                throw new BusinessException("图片验证码不正确");
            }

            //原则上来说service层返回的结果不应该是vo，要么是dto要么是po，但是这里为了减少一次数据库查询，直接就是返回vo
            UserInfoVO userInfoVO = userInfoService.login(email, password);
            return getSuccessResponseVO(userInfoVO);
        } finally {
            redisUtils.delete(Constants.REDIS_KEY_CHECK_CODE + checkCodeKey);
        }
    }

    /**
     * description: 获取系统设置
     *
     * @since: 1.0.0
     * @author: 作者拼音或者英文名称
     * @date: 2024/11/4 23:33
     */
    @RequestMapping("/getSysSetting")
    @GlobalInterceptor
    public ResponseVO getSysSetting() {
        return getSuccessResponseVO(redisComponent.getSysSetting());
    }
}
